import { Size } from 'cc';
import { _decorator, Component, Node, Sprite, SpriteFrame, Vec3 } from 'cc';
import { DiceStamp } from './DiceStamp';
import { size } from 'cc';
import { Prefab } from 'cc';
import { instantiate } from 'cc';
import { UITransform } from 'cc';
import { DiceState } from './Dice';
import { v3 } from 'cc';
const { ccclass, property, executeInEditMode } = _decorator;

export class MapData {
  private _data: number[];
  constructor(public size: Size) {
    this._data = new Array(size.width * size.height);
    for (let i = 0; i < this._data.length; i++) {
      this._data[i] = 0;
    }
  }

  get(x: number, y: number): number {
    return this._data[y * this.size.width + x];
  }

  set(x: number, y: number, value: number) {
    this._data[y * this.size.width + x] = value;
  }
}

@ccclass('MapStamp')
// @executeInEditMode(true)
export class MapStamp extends Component {
  @property(Size)
  gridSize: Size = new Size(100, 100);

  @property(Prefab)
  diceStampPfb: Prefab = null;

  @property(Size)
  _mapSize: Size = new Size(8, 8);

  @property(Size)
  get mapSize() {
    return this._mapSize;
  }

  set mapSize(value: Size) {
    this._mapSize = value;
    this.setupMap();
  }

  setupMap() {
    const mapData = this._mapData;


    for (let i = 0; i < this.mapSize.width; i++) {
      for (let j = 0; j < this.mapSize.height; j++) {
        const diceNode = instantiate(this.diceStampPfb);
        this.node.addChild(diceNode);
        const pos = this.getPosition(i, j);
        diceNode.setPosition(pos);
        const diceComp = diceNode.getComponent(DiceStamp);
        diceComp.diceSize = this.gridSize;
        diceComp.value = mapData.get(i, j);
      }
    }
  }

  private _mapData: MapData = new MapData(this.mapSize);

  getPosition(i: number, j: number): Vec3 {
    const mapUISizeCalcByGrid = new Size(this.gridSize.width * this.mapSize.width, this.gridSize.height * this.mapSize.height);
    const mapOffset = new Vec3(mapUISizeCalcByGrid.width / 2 - this.gridSize.width/2, mapUISizeCalcByGrid.height / 2 - this.gridSize.height/2, 0);
    return v3(i * this.gridSize.width - mapOffset.x, j * this.gridSize.height - mapOffset.y, 0)
  }

  onDiceRoll(diceState: DiceState){
    this.setMapData(diceState.position.x, diceState.position.y, diceState.bottom);
  }

  setMapData(x: number, y: number, value: number) {
    this._mapData.set(x, y, value);
    const diceNode = this.node.children[x * this.mapSize.height + y];
    const diceComp = diceNode.getComponent(DiceStamp);
    diceComp.value = value;
  }

  protected onLoad(): void {
    this.setupMap();
  }

  protected start(): void {

  }

  protected update(dt: number): void {

  }
}
